package com.xbongbong.pro.statistics.help;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mysql.cj.util.StringUtils;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.BiConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.XbbConstant;
import com.xbongbong.paas.domain.entity.PaasFormSubDataEntity;
import com.xbongbong.paas.domain.entity.ext.CkPaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.StatisticBiFormDataEntity;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.ReflectHelper;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.pro.bi.commons.pojo.AggFieldPojo;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.domain.entity.ChartEntity;
import com.xbongbong.pro.enums.IntervalTypeEnum;
import com.xbongbong.pro.service.toolbox.statistic.util.ChartResultUtil;
import com.xbongbong.pro.statistic.constant.ChartConstant;
import com.xbongbong.pro.statistic.enums.AdvancedComputingSecondEnum;
import com.xbongbong.pro.statistic.enums.ChartAggNameEnum;
import com.xbongbong.pro.statistic.enums.ChartTypeEnum;
import com.xbongbong.pro.statistic.enums.NumFormatEnum;
import com.xbongbong.pro.statistic.enums.YearChainEnum;
import com.xbongbong.pro.statistic.help.strategy.field.FieldAnalysisContext;
import com.xbongbong.pro.statistic.pojo.FieldAnalysisPojo;
import com.xbongbong.pro.statistic.pojo.SlaveSourcePojo;
import com.xbongbong.pro.statistic.result.pojo.FieldAttrPojo;
import com.xbongbong.pro.statistic.result.pojo.WarningValuePojo;
import com.xbongbong.pro.statistics.pojo.CkStatisticPojo;
import com.xbongbong.pro.statistics.service.CkPreParseResult;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.PaasFormSubDataModel;
import com.xbongbong.saas.service.toolbox.help.AttrDecimalPrecisionHelper;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * ck结果集帮助类
 * @author xinpeng.jiang
 * @version V1.0
 * @date 2021/11/17 15:39
 * @since V1.0
 */
@Component
public class CkResultHelp {
    public Logger logger = LoggerFactory.getLogger(getClass());


    @Resource
    private AttrDecimalPrecisionHelper attrDecimalPrecisionHelper;
    @Resource
    private FieldAnalysisContext fieldAnalysisContext;
    @Resource
    private UserModel userModel;
    @Resource
    private PaasFormSubDataModel paasFormSubDataModel;
    @Resource
    private IndexTypeModel indexTypeModel;


    @Autowired
    private Map<String, CkPreParseResult> preParseResultMap;


    /**
     * chartValue和chartValueSecond转换成jsonObject
     * @param chartEntity
     * @author xinpeng.jiang
     * @date 2021/11/16 14:38
     * @version 1.0
     */
    public void transformObj(ChartEntity chartEntity) {
        JSONArray chartValue = chartEntity.getChartValue();
        if (CollectionUtils.isNotEmpty(chartValue)) {
            JSONArray newValArr = new JSONArray(chartValue.size());
            for (Object obj : chartValue) {
                JSONObject valObj = JSON.parseObject(JSON.toJSONString(obj));
                newValArr.add(valObj);
            }
            chartEntity.setChartValue(newValArr);
        }
        // 双轴图
        JSONArray chartValueSecond = chartEntity.getChartValueSecond();
        if (CollectionUtils.isNotEmpty(chartValueSecond)) {
            JSONArray newValArr = new JSONArray(chartValueSecond.size());
            for (Object obj : chartValueSecond) {
                JSONObject valObj = JSON.parseObject(JSON.toJSONString(obj));
                newValArr.add(valObj);
            }
            chartEntity.setChartValueSecond(newValArr);
        }
    }

    /**
     * 统计图解析sql结果
     * @param resultArr ck查出来的数据
     * @param aggFieldMap ck映射map
     * @param classifyAttrPojo 分类
     * @param seriesAttrPojo 系列
     * @param classifyValMap key为分类的map，同环比用
     * @return java.util.List<java.util.LinkedHashMap < java.lang.String, com.xbongbong.pro.statistics.pojo.CkStatisticPojo>> 封装结果集
     * @author xinpeng.jiang
     * @date 2021/11/11 9:44
     * @version 1.0
     */
    public List<Map<String, CkStatisticPojo>> parseSqlResult(JSONArray resultArr, Map<String, AggFieldPojo> aggFieldMap, FieldAttrPojo classifyAttrPojo, FieldAttrPojo seriesAttrPojo, Map<String, String> classifyValMap, ChartEntity chartEntity) {
        List<Map<String, CkStatisticPojo>> classifyPojoList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(resultArr) && Objects.nonNull(classifyAttrPojo)) {
            Integer fieldType = classifyAttrPojo.getFieldType();
            int teamIdx = EsUtil.getTeamIdx(chartEntity, classifyAttrPojo.getFormId());
            int seriesTeamIdx = 0;
            if (Objects.nonNull(seriesAttrPojo)) {
                seriesTeamIdx = EsUtil.getTeamIdx(chartEntity, seriesAttrPojo.getFormId());
            }
            for (int i = 0; i < resultArr.size(); i++) {
                JSONObject resultObj = resultArr.getJSONObject(i);
                // 有分类
                Map<String, CkStatisticPojo> pojoMap4Classify = new LinkedHashMap<>();
                CkStatisticPojo classifyPojo = new CkStatisticPojo();
                classifyPojo.setFormId(classifyAttrPojo.getFormId());
                classifyPojo.setAttr(classifyAttrPojo.getAttr());
                classifyPojo.setKey(classifyAttrPojo.getAttr());
                String classifyVal;
                if (EsHelper.isTeamLogicByFieldType(fieldType, classifyAttrPojo.getBusinessType())) {
                    StringBuilder stringBuilder = getTeamValue(fieldType, teamIdx, resultObj);
                    classifyVal = stringBuilder.toString();
                }else if(Objects.equals(FieldTypeEnum.ADDRESS.getType(),fieldType) || Objects.equals(FieldTypeEnum.LOCATION.getType(),fieldType)){
                    classifyVal = FastJsonHelper.getStringOrDefault(resultObj, classifyAttrPojo.getAttr().replaceAll("\\.","_"), "");
                }else {
                    classifyVal = FastJsonHelper.getStringOrDefault(resultObj, classifyAttrPojo.getAttr(), "");
                    // 时间戳转毫秒
                    classifyVal = handleDate2Ms(fieldType, classifyVal);
                }
                //漏斗图特殊处理
                if(Objects.equals(ChartTypeEnum.FUNNEL.getCode(),chartEntity.getChartType())){
                    classifyVal = classifyVal.replace("[\"","").replace("\"]","");
                }
                // 特殊处理部门和分类的的value值为“0”时候的操作,修改为可穿透不可钻取
                if ((FieldTypeEnum.getDeptList().contains(classifyAttrPojo.getFieldType()) && Objects.equals(StringConstant.ZERO, classifyVal))
                        || (FieldTypeEnum.categoryList().contains(classifyAttrPojo.getFieldType()) && Objects.equals(StringConstant.ZERO, classifyVal))) {
                    classifyPojo.setValue("");
                } else {
                    classifyPojo.setValue(classifyVal);
                }
                //TODO
                // 有系列
                if (Objects.nonNull(seriesAttrPojo)) {
                    String seriesVal;
                    List<Map<String, CkStatisticPojo>> seriesPojoList = new ArrayList<>();
                    Map<String, CkStatisticPojo> seriesPojoMap = new LinkedHashMap<>();
                    CkStatisticPojo seriesPojo = new CkStatisticPojo();
                    seriesPojo.setFormId(seriesAttrPojo.getFormId());
                    seriesPojo.setAttr(seriesAttrPojo.getAttr());
                    seriesPojo.setKey(seriesAttrPojo.getAttr());
                    if (EsHelper.isTeamLogicByFieldType(seriesAttrPojo.getFieldType(), classifyAttrPojo.getBusinessType())) {
                        StringBuilder stringBuilder = getTeamValue(seriesAttrPojo.getFieldType(), seriesTeamIdx, resultObj);
                        seriesVal = stringBuilder.toString();
                    }else if(Objects.equals(FieldTypeEnum.ADDRESS.getType(),seriesAttrPojo.getFieldType()) || Objects.equals(FieldTypeEnum.LOCATION.getType(),seriesAttrPojo.getFieldType())){
                        seriesVal = FastJsonHelper.getStringOrDefault(resultObj, seriesAttrPojo.getAttr().replaceAll("\\.","_"), "");
                    } else {
                        seriesVal = FastJsonHelper.getStringOrDefault(resultObj, seriesAttrPojo.getAttr(), "");
                        // 时间戳转毫秒
                        seriesVal = handleDate2Ms(seriesAttrPojo.getFieldType(), seriesVal);
                    }
                    seriesPojo.setValue(seriesVal);
                    // 放统计结果
                    List<Map<String, CkStatisticPojo>> valuePojoList = getValuePojoList(aggFieldMap, resultObj, classifyVal, classifyValMap);
                    seriesPojo.setSub(valuePojoList);
                    seriesPojoMap.put(ChartAggNameEnum.AGG_SECOND.getStr(), seriesPojo);
                    seriesPojoList.add(seriesPojoMap);
                    classifyPojo.setSub(seriesPojoList);
                } else {
                    // 无系列，放统计结果
                    List<Map<String, CkStatisticPojo>> valuePojoList = getValuePojoList(aggFieldMap, resultObj, classifyVal, classifyValMap);
                    classifyPojo.setSub(valuePojoList);
                }
                pojoMap4Classify.put(ChartAggNameEnum.AGG_FIRST.getStr(), classifyPojo);
                classifyPojoList.add(pojoMap4Classify);
            }
        }
        return classifyPojoList;
    }
    
    public StringBuilder getTeamValue(Integer fieldType, int teamIdx, JSONObject resultObj) {
        String teamKey = null;
        if (FieldTypeEnum.OWNERID.getType().equals(fieldType)) {
            teamKey = XbbConstant.MY_TEAM_MAIN;
        }else if(FieldTypeEnum.COUSERID.getType().equals(fieldType)){
            teamKey = XbbConstant.MY_TEAM;
        }
        JSONArray teamMain = resultObj.getJSONArray(teamKey + teamIdx);
        StringBuilder stringBuilder = new StringBuilder();
        if(teamMain != null){
            for (int i1 = 0; i1 < teamMain.size(); i1++) {
                if (i1 > 0) {
                    stringBuilder.append(",");
                }
                stringBuilder.append(teamMain.get(i1));
            }
        }
        return stringBuilder;
    }

    /**
     * 将时间类型字段转化为毫秒
     * @param fieldType 类型
     * @param value 秒时间戳
     * @return java.lang.String 毫秒时间戳
     * @author xinpeng.jiang
     * @date 2021/12/2 16:14
     * @version 1.0
     */
    public String handleDate2Ms(Integer fieldType, String value) {
        if(StringUtil.isEmpty(value)){
            return value;
        }
        FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
        if (Objects.nonNull(fieldTypeEnum) && StringConstant.DATE.equals(fieldTypeEnum.getEsalias())) {
            value = String.valueOf(Long.parseLong(value) * 1000);
        }
        return value;
    }

    /**
     * 获取最后一层值（统计结果）
     * @param aggFieldMap ck映射对照
     * @param resultObj 数据集合
     * @param classifyVal 分类key
     * @param classifyValMap key:分类，value:统计值
     * @return 封装好的pojoList
     */
    private List<Map<String, CkStatisticPojo>> getValuePojoList(Map<String, AggFieldPojo> aggFieldMap, JSONObject resultObj, String classifyVal, Map<String, String> classifyValMap) {
        List<Map<String, CkStatisticPojo>> valuePojoList = new ArrayList<>();
        for (Map.Entry<String, AggFieldPojo> aggFieldPojoEntry : aggFieldMap.entrySet()) {
            String originKey = aggFieldPojoEntry.getKey();
            AggFieldPojo aggFieldPojo = aggFieldPojoEntry.getValue();
            // todo 无穷
            String value = FastJsonHelper.getStringOrDefault(resultObj, originKey, "");
            if (StringUtil.isEmpty(value)) {
                value = "0";
            }
            // 拼接key
            StringBuilder keyBuilder = new StringBuilder(ChartAggNameEnum.SUM_TOTAL.getStr());
            keyBuilder.append("&").append(aggFieldPojo.getFormId());
            keyBuilder.append("&").append(aggFieldPojo.getAttr());
            keyBuilder.append("&").append(aggFieldPojo.getAxis() == null ? PaasConstant.LEFT : aggFieldPojo.getAxis());
            keyBuilder.append("&").append(aggFieldPojo.getIndex() == null ? 0 : aggFieldPojo.getIndex());
            String key = keyBuilder.toString();
            // 统计值map
            CkStatisticPojo valuePojo = new CkStatisticPojo();
            valuePojo.setKey(key);
            valuePojo.setValue(value);
            Map<String, CkStatisticPojo> valuePojoMap = new LinkedHashMap<>();
            valuePojoMap.put(key, valuePojo);
            valuePojoList.add(valuePojoMap);
            // 分类map
            keyBuilder.append("&").append(classifyVal);
            classifyValMap.put(keyBuilder.toString(), value);
        }
        return valuePojoList;
    }
    

    /**
     * 同环比差值处理
     * @param dateFieldAttrPojo 日期pojo
     * @param advancedComputing 高级计算
     * @param nowTimestamp 当期值时间戳
     * @return java.lang.Long 差值时间戳
     * @author xinpeng.jiang
     * @date 2021/11/25 9:49
     * @version 1.0
     */
    public Long getYearChainDiff(FieldAttrPojo dateFieldAttrPojo, JSONArray advancedComputing, Long nowTimestamp) {
        Long oldTimestamp = null;
        if (CollectionUtils.isEmpty(advancedComputing) || advancedComputing.size() < 2) {
            return oldTimestamp;
        }
        String secondType = advancedComputing.getString(1);
        IntervalTypeEnum intervalTypeEnum = IntervalTypeEnum.getByFormatStr(dateFieldAttrPojo.getDateGroupType());
        // 获取差值
        if (Objects.equals(AdvancedComputingSecondEnum.getYearOrChain(secondType), YearChainEnum.YEAR_ON_YEAR.getValue())) {
            // 同比
            oldTimestamp = getYearOnYear(nowTimestamp);
        } else if (Objects.equals(AdvancedComputingSecondEnum.getYearOrChain(secondType), YearChainEnum.CHAIN_ON_CHAIN.getValue())) {
            // 环比
            oldTimestamp = getChainOnChain(intervalTypeEnum, nowTimestamp);
        }
        return oldTimestamp;
    }

    /**
     * 同比
     * @param nowTimestamp 当期值时间戳
     * @return java.lang.Long 差值时间戳
     * @author xinpeng.jiang
     * @date 2021/11/25 9:54
     * @version 1.0
     */
    private Long getYearOnYear(Long nowTimestamp) {
        Calendar oldDate = Calendar.getInstance();
        oldDate.setTimeInMillis(nowTimestamp);
        oldDate.add(Calendar.YEAR, -1);
        return oldDate.getTimeInMillis();
    }
    
    /**
     * 环比
     * @param intervalTypeEnum 日期类型
     * @param nowTimestamp 当期值时间戳
     * @return java.lang.Long 差值时间戳
     * @author xinpeng.jiang
     * @date 2021/11/25 9:54
     * @version 1.0
     */
    private Long getChainOnChain(IntervalTypeEnum intervalTypeEnum, Long nowTimestamp) {
        Calendar date = Calendar.getInstance();
        date.setTimeInMillis(nowTimestamp);
        switch (intervalTypeEnum) {
            case YEAR:
                date.add(Calendar.YEAR, -1);
                break;
            case YEAR_QUARTER:
                date.add(Calendar.MONTH, -3);
                break;
            case YEAR_MONTH:
                date.add(Calendar.MONTH, -1);
                break;
            case YEAR_MONTH_DAY:
                date.add(Calendar.DATE, -1);
                break;
            default:
                break;
        }
        return date.getTimeInMillis();
    }


    /**
     * 字段对应解析
     * 统计表查询多业务关联的时候没办法直接难道关联隐藏,在查一次
     * @param field        字段属性
     * @param corpId       公司ID
     * @param values       字段值
     * @param chartEntity  图表实体
     * @param isChart      图和表的判断标记 true为图或统计表 false为查询表
     * @param dataIdToEsId 团队查询中需要的父EsId和dataID关系对应
     * @return value字段值对应的字段解析内容
     * @author zhouwq
     * @date 2019/4/15 17:03
     */
    public Map<String, String> valueListAnalysis(FieldAttrPojo field, String corpId, List<String> values, ChartEntity chartEntity,
                                                 Boolean isChart, Map<String, String> dataIdToEsId, Boolean isGroupField, BaseDTO baseDTO,Boolean isWarningSync) throws XbbException{
        return valueListAnalysis(field, corpId,  values,  chartEntity, isChart,  dataIdToEsId,  isGroupField,  baseDTO, isWarningSync,null);
    }
    public Map<String, String> valueListAnalysis(FieldAttrPojo field, String corpId, List<String> values, ChartEntity chartEntity,
                                                 Boolean isChart, Map<String, String> dataIdToEsId, Boolean isGroupField, BaseDTO baseDTO,Boolean isWarningSync,Map<String, Map<String, String>> attrLinkMap) throws XbbException{
        Map<String, String> results = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<String> valueResults = new ArrayList<>();
        Integer fieldType = field.getFieldType();
        Integer amountFlag = field.getAmountFlag();
        Integer integerOnly = field.getIntegerOnly();
        Integer businessType = field.getBusinessType();
        FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
        if (values.size() > 0) {
            values.forEach(value -> {
                String result = "";
                //value为null时给空字符串
                if (Objects.nonNull(value)) {
                    result = ((ChartConstant.LEFT_PARENTHESES + ChartConstant.RIGHT_PARENTHESES).equals(value)) ? "" : value;
                }
                //处理ES查询数字返回为double类型的数据
                String splitStr = ".0";
                String splitTwoStr = ".00";
                if (result.endsWith(splitStr)) {
                    result = result.substring(0, result.length() - 2);
                } else if (result.endsWith(splitTwoStr)) {
                    result = result.substring(0, result.length() - 3);
                }
                if (Objects.equals(1, integerOnly)) {
                    field.setAccuracy(BasicConstant.ZERO);
                }
                valueResults.add(result);
            });
            if (fieldTypeEnum != null) {
                FieldAnalysisPojo fieldAnalysisPojo = new FieldAnalysisPojo(chartEntity, values, valueResults, field, dataIdToEsId, corpId, isGroupField, isChart, businessType, isWarningSync);
                BeanUtil.copyProperties(baseDTO, fieldAnalysisPojo);
                //协同人团队或负责人团队
                if(EsHelper.isTeamLogicByBusinessType(fieldAnalysisPojo.getBusinessType())  && (Objects.equals(fieldTypeEnum.getType(),FieldTypeEnum.OWNERID.getType()) || Objects.equals(fieldTypeEnum.getType(),FieldTypeEnum.COUSERID.getType()) )) {
                    String corpid = fieldAnalysisPojo.getCorpid();
                    if(!fieldAnalysisPojo.getIsGroupField()){
                        Set<String> userIdSet = new HashSet<>();
                        List<String> valuesResult = fieldAnalysisPojo.getValuesResult();
                        Map<String, List<String>> map = new LinkedHashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        for (String s : valuesResult) {
                            if (StringUtils.isNullOrEmpty(s)){
                                continue;
                            }
                            JSONObject jsonObject = JSON.parseObject(s);
                            if (jsonObject == null) {
                                continue;
                            }
                            Collection<Object> list = jsonObject.values();
                            if (CollectionsUtil.isNotEmpty(list)) {
                                JSONArray jsonArray = JSONArray.parseArray(list.toArray()[0].toString());
                                List<String> userIds = new ArrayList<>();
                                for (Object o : jsonArray) {
                                    userIds.add(o.toString());
                                    userIdSet.add(o.toString());
                                }
                                map.put(jsonObject.keySet().toArray()[0].toString(), userIds);
                            }
                        }
                        Map<String, String> finalResults = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        getUserMap(corpid, userIdSet, finalResults);
                        for (String s : map.keySet()) {
                            List<String> list = map.get(s);
                            StringBuilder stringBuilder = new StringBuilder();
                            for (int i = 0; i < list.size(); i++) {
                                if (i > 0) {
                                    stringBuilder.append(",");
                                }
                                stringBuilder.append(finalResults.get(list.get(i)));
                            }
                            results.put(s, stringBuilder.toString());
                        }
                    }else {
                        List<String> valuesResult = fieldAnalysisPojo.getValuesResult();
                        Set<String> userIdSet = new HashSet<>();
                        for (String s : valuesResult) {
                            if(StringUtil.isEmpty(s)){
                                continue;
                            }
                            if(s.contains(",")){
                                String[] array = s.split(",");
                                userIdSet.addAll(Arrays.asList(array));
                            }else {
                                userIdSet.add(s);
                            }
                        }
                        Map<String, String> finalResults = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        getUserMap(corpid, userIdSet, finalResults);
                        for (String userId : valuesResult) {
                            if(StringUtil.isEmpty(userId)){
                                results.put(userId, userId);
                            }else {
                                String userName;
                                if(userId.contains(",")){
                                    String[] array = userId.split(",");
                                    StringBuilder stringBuilder = new StringBuilder();
                                    for (int i = 0; i < array.length; i++) {
                                        if (i > 0) {
                                            stringBuilder.append(",");
                                        }
                                        stringBuilder.append(finalResults.get(array[i]));
                                    }
                                    userName = stringBuilder.toString();
                                }else {
                                    userName = finalResults.get(userId);
                                }
                                results.put(userId, userName);
                            }
                        }
                    }

                }else if(Objects.equals(fieldType, FieldTypeEnum.LINK_BUSINESS_SINGLE.getType()) || Objects.equals(fieldType, FieldTypeEnum.LINK_BUSINESS_MULTI.getType())
                        || Objects.equals(fieldType, FieldTypeEnum.LINK_RECEIVER.getType())){
                    String attr = field.getAttr();
                    if(!EsUtil.getSingle(chartEntity)){
                        attr = field.getOriginalAttr();
                    }
                    results =  attrLinkMap.get(attr);
                } else {
                    fieldAnalysisContext.initStrategy(fieldTypeEnum);
                    results = fieldAnalysisContext.strategyMethod(fieldAnalysisPojo);
                }
            } else {
                for (int i = 0; i < values.size(); i++) {
                    results.put(values.get(i), valueResults.get(i));
                }
            }
        }
        //将结果集合中的key置为初始传进来的values
        for (int i = 0; i < valueResults.size(); i++) {
            String value = values.get(i);
            String valueResult = results.remove(valueResults.get(i));
            if (value != null && valueResult != null) {
                results.put(value, valueResult);
            }
        }
        return results;
    }

    private void getUserMap(String corpid, Set<String> userIdSet, Map<String, String> finalResults) {
        List<UserEntity> userEntities = userModel.getUserNamesAllByIdIn(corpid, new ArrayList<>(userIdSet));
        userEntities.forEach((UserEntity userEntity) -> finalResults.put(userEntity.getUserId(), userEntity.getName()));
    }

    /**
     * 获取格式化的数字字符串
     * @param fieldAttrPojo 统计值pojo
     * @param valueList 格式化前的值集合
     * @return java.lang.String 格式化后的值
     * @author xinpeng.jiang
     * @date 2021/12/9 15:16
     * @version 1.0
     */
    public void getNumFormat(FieldAttrPojo fieldAttrPojo, List<String> valueList) {
        if (fieldAttrPojo == null) {
            return;
        }
        int accuracy = fieldAttrPojo.getAccuracy() == null ? 0 : fieldAttrPojo.getAccuracy();
        Integer percentUsed = fieldAttrPojo.getPercentUsed();
        Integer groupingUsed = fieldAttrPojo.getGroupingUsed() == null ? fieldAttrPojo.getAmountFlag() : fieldAttrPojo.getGroupingUsed();
        Integer numFormat = fieldAttrPojo.getNumFormat();
        // 使用数值格式
        NumFormatEnum numFormatEnum = NumFormatEnum.getByCode(numFormat);
        String unit = numFormatEnum.getNoYuanUnit();
        for (int i = 0; i < valueList.size(); i++) {
            String value = valueList.get(i);
            if (StringUtil.isEmpty(value) || Objects.equals(value, StringConstant.SHORT_BARS)) {
                continue;
            }
            // 百分比要先扩两位小数，后面再减
            if (Objects.equals(percentUsed, 1)) {
                accuracy += 2;
            }
            String newVal = String.valueOf(ChartResultUtil.formatVal4Num(new BigDecimal(value), numFormatEnum, accuracy));
            if (Objects.equals(percentUsed, 1)) {
                accuracy -= 2;
            }
            String formatVal = attrDecimalPrecisionHelper.getNumberFormat(newVal, accuracy, groupingUsed, percentUsed);
            if (StringUtil.isNotEmpty(unit)) {
                formatVal += unit;
            }
            valueList.set(i, formatVal);
        }
    }

    /**
     * 导出子表单解析
     * @param resultArr 原始数据
     * @param chartEntity
     * @param subformAttrMap 只存放子表单attr，结构：formId->原attr->新attr
     * @throws XbbException
     * @author xinpeng.jiang
     * @date 2021/12/20 16:28
     * @version 1.0
     */
    public void handleSubFormData4Export(JSONArray resultArr, ChartEntity chartEntity, Map<Long, Map<String, String>> subformAttrMap, Integer subFiledBusinessType,Integer subFiledSaasMark) throws XbbException, IllegalAccessException {
        if (CollectionUtils.isEmpty(resultArr)) {
            return;
        }
        boolean isSingle = EsUtil.getSingle(chartEntity);
        IndexTypeEnum indexTypeEnum = indexTypeModel.getSubIndexType(chartEntity.getCorpid(), subFiledBusinessType, subFiledSaasMark);
        // 封装主数据id
        List<Long> dataIdList = new ArrayList<>();
        for (int i = 0; i < resultArr.size(); i++) {
            JSONObject result = resultArr.getJSONObject(i);
            if (isSingle) {
                Long dataId = FastJsonHelper.getLongOrDefault(result, StringConstant.DATA_ID, null);
                if (dataId != null) {
                    dataIdList.add(dataId);
                }
            } else {
                // 目前从表最多6个，先写死，后期加需要改常量
                for (int j = 0; j < BiConstant.SLAVE_FORM_NUM; j++) {
                    Long dataId = FastJsonHelper.getLongOrDefault(result, StringConstant.DATA_ID + StringConstant.CROSS + (j+1) , null);
                    if (dataId != null) {
                        dataIdList.add(dataId);
                    }
                }
            }
        }
        // 获取子表单结果
        Map<String, Object> params = new HashMap<>(2);
        params.put(StringConstant.CORPID, chartEntity.getCorpid());
        params.put(ParameterConstant.DATA_ID_IN, dataIdList);
        List<? extends PaasFormSubDataEntity> formSubDataList = paasFormSubDataModel.getSubDataList(params, indexTypeEnum);
        // 组建map
        Map<Long, Map<Long, Map<String, JSONArray>>> subMap = new HashMap<>();
        for (PaasFormSubDataEntity subDataEntity : formSubDataList) {
            JSONObject data = subDataEntity.getData();
            data.put(BusinessConstant.SUB_DATA_ID, subDataEntity.getId());
            subDataEntity.setData(data);
            subMap.computeIfAbsent(subDataEntity.getDataId(), v -> new HashMap<>()).computeIfAbsent(subDataEntity.getFormId(), v -> new HashMap<>()).computeIfAbsent(subDataEntity.getAttr(), v -> new JSONArray()).add(data);
        }
        // 用反射把子表单数据填回主数据
        for (int i = 0; i < resultArr.size(); i++) {
            Object result = resultArr.get(i);
            if (isSingle) {
                // 单表
                CkPaasFormDataEntityExt ckPaasFormDataEntityExt = JSON.parseObject(JSON.toJSONString(result), CkPaasFormDataEntityExt.class);
                Map<Long, Map<String, JSONArray>> formIdMap = subMap.get(ckPaasFormDataEntityExt.getDataId());
                if (formIdMap == null) {
                    continue;
                }
                for (Map.Entry<Long, Map<String, String>> attrMap : subformAttrMap.entrySet()) {
                    Long formId = attrMap.getKey();
                    Map<String, JSONArray> dataMap = formIdMap.get(formId);
                    if (dataMap == null) {
                        continue;
                    }
                    dataMap.forEach((k, v) -> ReflectHelper.valueSet(ckPaasFormDataEntityExt, k, v));
                }
                resultArr.set(i, JSON.parseObject(JSON.toJSONString(ckPaasFormDataEntityExt)));
            } else {
                // 多表
                StatisticBiFormDataEntity statisticBiFormDataEntity = JSON.parseObject(JSON.toJSONString(result), StatisticBiFormDataEntity.class);
                // 目前从表最多6个，先写死，后期加需要改常量
                for (int j = 0; j < BiConstant.SLAVE_FORM_NUM; j++) {
                    Long dataId = (Long) ReflectHelper.valueGet(statisticBiFormDataEntity, StringConstant.DATA_ID + StringConstant.CROSS + (j+1));
                    Map<Long, Map<String, JSONArray>> formIdMap = subMap.get(dataId);
                    if (formIdMap == null) {
                        continue;
                    }
                    for (Map.Entry<Long, Map<String, String>> attrMap : subformAttrMap.entrySet()) {
                        // 用原始subform key获取多表合并后的subform key
                        Long formId = attrMap.getKey();
                        Map<String, String> originalAttrMap = attrMap.getValue();
                        Map<String, JSONArray> dataMap = formIdMap.get(formId);
                        if (dataMap == null) {
                            continue;
                        }
                        // k:旧attr，v:新attr
                        originalAttrMap.forEach(
                                (k, v) -> {
                                    JSONArray jsonArray = dataMap.get(k);
                                    if (CollectionUtils.isNotEmpty(jsonArray)) {
                                        ReflectHelper.valueSet(statisticBiFormDataEntity, v, jsonArray);
                                    }
                                });
                    }
                }
                resultArr.set(i, JSON.parseObject(JSON.toJSONString(statisticBiFormDataEntity)));
            }
        }
    }

    /**
     * 是否是穿透
     * @param filter  筛选条件
     * @return
     */
    public boolean getPenetrateFlag(JSONArray filter) {
        boolean penetrateFlag = false;
        if(CollectionUtils.isEmpty(filter)){
            return penetrateFlag;
        }
        for (int i = 0; i < filter.size(); i++) {
            JSONObject jsonObject = filter.getJSONObject(i);
            if (Objects.equals(jsonObject.getInteger("penetrateFlag"), BasicConstant.ONE)) {
                penetrateFlag = true;
                break;
            }
        }
        return penetrateFlag;
    }

    /**
     * 获取格式化的数字字符串
     * @param fieldAttrPojo 统计值pojo
     * @param warningValues 格式化前的值集合
     * @return java.lang.String 格式化后的值
     * @author xinpeng.jiang
     * @date 2021/12/9 15:16
     * @version 1.0
     */
    public void getNumFormat4Dw(FieldAttrPojo fieldAttrPojo, List<WarningValuePojo> warningValues) {
        if (fieldAttrPojo == null || CollectionsUtil.isEmpty(warningValues)) {
            return;
        }
        int accuracy = fieldAttrPojo.getAccuracy() == null ? 0 : fieldAttrPojo.getAccuracy();
        Integer percentUsed = fieldAttrPojo.getPercentUsed();
        Integer groupingUsed = fieldAttrPojo.getGroupingUsed() == null ? fieldAttrPojo.getAmountFlag() : fieldAttrPojo.getGroupingUsed();
        Integer numFormat = fieldAttrPojo.getNumFormat();
        // 使用数值格式
        NumFormatEnum numFormatEnum = NumFormatEnum.getByCode(numFormat);
        String unit = numFormatEnum.getNoYuanUnit();
        for (int i = 0; i < warningValues.size(); i++) {
            WarningValuePojo warningValuePojo = warningValues.get(i);
            String value = warningValuePojo.getValue();
            if (StringUtil.isEmpty(value) || Objects.equals(value, StringConstant.SHORT_BARS)) {
                warningValuePojo.setValue("");
                continue;
            }
            String newVal = String.valueOf(ChartResultUtil.formatVal4Num(new BigDecimal(value), numFormatEnum, accuracy));
            String formatVal = attrDecimalPrecisionHelper.getNumberFormat(newVal, accuracy, groupingUsed, percentUsed);
            if (StringUtil.isNotEmpty(unit)) {
                formatVal += unit;
            }
            warningValuePojo.setValue(formatVal);
        }
    }

    /**
     * 获取字段展示时的拼接后缀
     * @param advancedComputing 汇总字段高级计算规则
     * @return String 拼接的后缀  ( - ) 或者 ( )
     * @author zyy
     * @date 2022/03/08 17:18
     * @version 1.0
     */
    public String splicingSuffix(JSONArray advancedComputing, ChartTypeEnum chartTypeEnum) {
        //如果存在高级计算规则 -> 需拼接后缀
        if(CollectionsUtil.isEmpty(advancedComputing) || advancedComputing.size() < 2){
            if(ChartTypeEnum.DATA_STATISTICS_TABLE.equals(chartTypeEnum)){
                return StringConstant.RIGHT_BRACKETS;
            }
            return "";
        }
        StringBuilder sb = new StringBuilder();
        AdvancedComputingSecondEnum computingSecondEnum = AdvancedComputingSecondEnum.getByAlias(advancedComputing.getString(1));
        if(!Objects.isNull(computingSecondEnum)){
            //统计表时格式为  - xx )
            if(ChartTypeEnum.DATA_STATISTICS_TABLE.equals(chartTypeEnum)){
                sb.append(StringConstant.SPLIT_LINE);
            }else{
                //其余情况为 ( xx )
                sb.append(StringConstant.LEFT_BRACKETS);
            }
            sb.append(I18nMessageUtil.getMessage(computingSecondEnum.getName()));
            sb.append(StringConstant.RIGHT_BRACKETS);
        }
        return sb.toString();
    }

    /**
     * 重新组装结果集 （漏斗图 && 分类字段为复选）
     *
     * @param resultArray  结果集
     * @param chartEntity  图表实体
     * @param aggFieldMap  值的映射map
     * @author zyy
     * @date 2022/5/7
     * @version v1.0
     */
    public JSONArray preParseResultArray(JSONArray resultArray,ChartEntity chartEntity,Map<String, AggFieldPojo> aggFieldMap) throws XbbException {
        for (Map.Entry<String, CkPreParseResult> parseResultEntry : preParseResultMap.entrySet()) {
            if(Objects.equals(chartEntity.getChartType(),parseResultEntry.getValue().getCode())){
                return parseResultEntry.getValue().preParseResultArray(resultArray,chartEntity,aggFieldMap);
            }
        }
        return resultArray;
    }
}
